package com.jacobson.core.widget.adapter

import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.jacobson.core.framework.delegation.WeakRef
import com.jacobson.core.widget.logger.LoggerFactory

/**
 * ================================================
 *
 *  @author Wucz on 2018/10/9 17:55
 * ================================================
 */
abstract class DelegationAdapter<T>(
        context: Context,
        private val delegatesManager: AdapterDelegatesManager<T> = AdapterDelegatesManager(),
        protected var items: T? = null
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    protected val logger = LoggerFactory.getLogger()
    protected val context by WeakRef { context }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return delegatesManager.onCreateViewHolder(parent, viewType)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        delegatesManager.onBindViewHolder(items, holder, position, null)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>) {
        delegatesManager.onBindViewHolder(items, holder, position, payloads)
    }

    override fun getItemViewType(position: Int): Int {
        return delegatesManager.getItemViewType(items, position)
    }

    override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
        delegatesManager.onViewRecycled(holder)
    }

    override fun onFailedToRecycleView(holder: RecyclerView.ViewHolder): Boolean {
        return delegatesManager.onFailedToRecycleView(holder)
    }

    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
        delegatesManager.onViewAttachedToWindow(holder)
    }

    override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
        delegatesManager.onViewDetachedFromWindow(holder)
    }

    fun addDelegate(delegate: AdapterDelegate<T>): DelegationAdapter<*> {
        delegatesManager.addDelegate(delegate)
        return this
    }

    fun addDelegate(viewType: Int, delegate: AdapterDelegate<T>): DelegationAdapter<*> {
        delegatesManager.addDelegate(viewType, delegate)
        return this
    }

    fun addDelegate(viewType: Int, allowReplacingDelegate: Boolean, delegate: AdapterDelegate<T>): DelegationAdapter<*> {
        delegatesManager.addDelegate(viewType, allowReplacingDelegate, delegate)
        return this
    }

    fun removeDelegate(delegate: AdapterDelegate<T>): DelegationAdapter<*> {
        delegatesManager.removeDelegate(delegate)
        return this
    }

    fun removeDelegate(viewType: Int): DelegationAdapter<*> {
        delegatesManager.removeDelegate(viewType)
        return this
    }

    fun clearDelegates(): DelegationAdapter<*> {
        delegatesManager.clearDelegates()
        return this
    }
}